# cron: 23 56 23 * * *
# new Env("百事通每日统计")
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os
import re
import glob
import time
import logging
from datetime import datetime, timedelta

# 配置日志格式（带时间戳）
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S'
)
logger = logging.getLogger()

# ====================== 配置区域 ======================
LOG_DIR_PATTERN = "/ql/data/log/WXyuedu_百事通*"  # 日志目录模式（支持通配符）
BALANCE_DIVISOR = 1                              # 余额转换除数（厘转元）
WITHDRAWAL_DIVISOR = 1                              # 提现转换除数（元转元）
DEBUG_MODE = False                                  # 设置为True启用调试日志
# =====================================================

# 在logger定义后设置调试模式
if DEBUG_MODE:
    logger.setLevel(logging.DEBUG)
    logger.debug("调试模式已启用")

def parse_log_files():
    """解析日志文件并提取账号数据"""
    start_time = time.time()
    logger.info("开始日志分析任务")
    
    # 计算时间范围（最近24小时）
    time_threshold = datetime.now() - timedelta(hours=24)
    logger.info(f"分析时间范围: {time_threshold.strftime('%Y-%m-%d %H:%M:%S')} 至今")
    
    account_data = {}
    processed_files = 0
    skipped_files = 0

    # 遍历匹配的日志目录
    for log_dir in glob.glob(LOG_DIR_PATTERN):
        if not os.path.isdir(log_dir):
            logger.warning(f"跳过非目录项: {log_dir}")
            continue
            
        logger.info(f"处理目录: {log_dir}")
        
        # 遍历目录中的日志文件
        for filename in os.listdir(log_dir):
            if not filename.endswith('.log'):
                continue
                
            file_path = os.path.join(log_dir, filename)
            
            # 从文件名解析时间戳（格式：2025-06-13-19-27-03-258.log）
            try:
                file_time = datetime.strptime(filename[:19], "%Y-%m-%d-%H-%M-%S")
                if file_time < time_threshold:
                    skipped_files += 1
                    if DEBUG_MODE:
                        logger.debug(f"跳过旧文件: {filename} ({file_time})")
                    continue
            except Exception as e:
                logger.error(f"文件时间解析失败: {filename} - {str(e)}")
                continue
                
            # 处理日志文件
            try:
                if DEBUG_MODE:
                    logger.info(f"分析文件: {filename}")
                with open(file_path, 'r', encoding='utf-8') as f:
                    current_account = None
                    current_run = None
                    
                    for line in f:
                        line = line.strip()
                        
                        # 识别账号 - 匹配格式: [INFO] ===> [账号名]开始运行
                        account_match = re.search(r'\[INFO\]\s+===>\s+\[(.*?)\]开始运行', line)
                        if account_match:
                            # 保存上一个账号的运行数据
                            if current_account and current_run:
                                # 确保至少有一个余额记录
                                if current_run['initial_balance'] is not None or current_run['withdrawals']:
                                    if current_account not in account_data:
                                        account_data[current_account] = []
                                    account_data[current_account].append(current_run)
                                    if DEBUG_MODE:
                                        logger.debug(f"保存账号运行数据: {current_account} - 运行 {len(account_data[current_account])}")
                            
                            # 开始新账号
                            current_account = account_match.group(1)
                            current_run = {
                                'initial_balance': None,
                                'final_balance': None,
                                'withdrawals': []
                            }
                            if DEBUG_MODE:
                                logger.debug(f"新账号开始: {current_account}")
                            continue
                            
                        if not current_account or not current_run:
                            continue
                            
                        # 识别余额 - 匹配格式: [INFO] ===> 当前余额[数值]
                        balance_match = re.search(r'\[INFO\]\s+===>\s+当前余额\[([\d.]+)\]', line)
                        if balance_match:
                            try:
                                # 余额单位是厘，需要除以1000转换为元
                                amount = float(balance_match.group(1)) / BALANCE_DIVISOR
                                
                                # 如果是第一次记录余额，保存为初始余额
                                if current_run['initial_balance'] is None:
                                    current_run['initial_balance'] = amount
                                    if DEBUG_MODE:
                                        logger.debug(f"初始余额记录: {current_account} - {amount:.2f}元")
                                
                                # 更新当前余额
                                current_run['final_balance'] = amount
                                if DEBUG_MODE:
                                    logger.debug(f"余额记录: {current_account} - {amount:.2f}元")
                            except ValueError:
                                logger.warning(f"金额转换失败: {balance_match.group(1)}")
                            continue
                            
                        # 修复提现识别 - 匹配格式: [INFO] ===> 提现[数值元]
                        # 示例: [INFO] ===> 提现[1元]
                        withdrawal_match = re.search(r'\[INFO\]\s+===>\s+提现\[([\d.]+)\]', line)
                        if withdrawal_match:
                            try:
                                # 提现单位已经是元，不需要转换
                                amount = float(withdrawal_match.group(1)) / WITHDRAWAL_DIVISOR
                                current_run['withdrawals'].append(amount)
                                
                                # 更新当前余额：减去提现金额
                                if current_run['final_balance'] is not None:
                                    current_run['final_balance'] -= amount
                                    if DEBUG_MODE:
                                        logger.debug(f"提现后余额更新: {current_account} - 余额: {current_run['final_balance']:.2f}元")
                                
                                if DEBUG_MODE:
                                    logger.debug(f"提现记录: {current_account} - {amount:.2f}元")
                            except ValueError:
                                logger.warning(f"提现金额转换失败: {withdrawal_match.group(1)}")
                            continue
                            
                        # 新增匹配提现结果记录 - 示例: [INFO] ===> 提现结果[提现已受理,请留意]
                        result_match = re.search(r'\[INFO\]\s+===>\s+提现\[([\d.]+)\]结果.*提现已提交', line)
                        if result_match and current_run['withdrawals']:
                            if DEBUG_MODE:
                                logger.debug(f"提现确认: {current_account} - 提现已提交")
                
                # 保存最后一个账号的数据
                if current_account and current_run:
                    # 确保至少有一个余额记录或提现记录
                    if current_run['initial_balance'] is not None or current_run['withdrawals']:
                        if current_account not in account_data:
                            account_data[current_account] = []
                        account_data[current_account].append(current_run)
                        if DEBUG_MODE:
                            logger.debug(f"保存最后一个账号数据: {current_account} - 初始余额: {current_run['initial_balance']} 最终余额: {current_run['final_balance']} 提现: {current_run['withdrawals']}")
                
                processed_files += 1
            except Exception as e:
                logger.error(f"文件解析失败: {file_path} - {str(e)}")
    
    logger.info(f"文件处理完成: 已处理 {processed_files} 个文件, 跳过 {skipped_files} 个")
    logger.info(f"日志解析耗时: {time.time() - start_time:.2f} 秒")
    return account_data

def generate_report(account_data):
    """生成统计报告"""
    start_time = time.time()
    logger.info("开始生成报告")
    
    if not account_data:
        return "未找到有效的账号数据", 0, 0, 0
    
    report_lines = ["📊 应用账号收益日报"]
    total_runs = 0
    total_balance = 0.0
    total_withdrawals = 0.0
    
    # 处理每个账号数据
    for account, runs in account_data.items():
        if not runs:
            continue
            
        account_line = [f"\n✅ 账号 [{account}]:"]
        today_withdrawals = 0.0
        account_warnings = 0
        account_has_withdrawal = False  # 标记账号是否有提现
        first_balance = None  # 第一次运行的初始余额
        last_balance = None   # 最后一次运行的最终余额
        
        # 处理每次运行
        for run_idx, run_data in enumerate(runs, 1):
            initial_balance = run_data.get('initial_balance', 0.0)
            final_balance = run_data.get('final_balance', 0.0)
            withdrawals = run_data.get('withdrawals', [])
            
            # 保存第一次运行的初始余额
            if run_idx == 1:
                first_balance = initial_balance
            
            # 保存最后一次运行的最终余额
            if run_idx == len(runs):
                last_balance = final_balance
            
            # 统计全局数据
            total_runs += 1
            total_balance += final_balance
            run_withdrawals = sum(withdrawals)
            total_withdrawals += run_withdrawals
            today_withdrawals += run_withdrawals
            
            # 检查是否有提现
            if run_withdrawals > 0:
                account_has_withdrawal = True
            
            # 添加本次运行信息
            run_info = f"第{run_idx}次{final_balance:.2f}元"
            run_info += f" 提现{run_withdrawals:.2f}元"
            
            # 异常检测：当第一次的余额=末次余额且无提现时标记⚠️
            if initial_balance is not None and final_balance is not None:
                # 考虑浮点数精度问题
                if abs(initial_balance - final_balance) < 0.001 and not withdrawals:
                    run_info += " ⚠️"
                    account_warnings += 1
                    if DEBUG_MODE:
                        logger.debug(f"异常检测: {account} 第{run_idx}次 - 初始余额={initial_balance:.2f}, 最终余额={final_balance:.2f}, 无提现")
            
            account_line.append(run_info)
        
        # 添加总结信息
        account_line.append(f"最后余额: {last_balance:.2f}元")
        account_line.append(f"今日提现: {today_withdrawals:.2f}元")
        
        # 检查整个账号是否异常
        account_abnormal = False
        if (first_balance is not None and 
            last_balance is not None and 
            abs(first_balance - last_balance) < 0.001 and 
            not account_has_withdrawal and 
            len(runs) > 0):
            account_line.append("🔴 账号异常")
            account_abnormal = True
        
        # 显示异常运行次数（如果不显示整个账号异常）
        if account_warnings and not account_abnormal:
            account_line.append(f"异常运行: {account_warnings}次")
        
        report_lines.append(" ".join(account_line))
    
    # 添加全局汇总
    report_lines.append("\n📈 全局汇总:")
    report_lines.append(f"- 总运行次数: {total_runs}次")
    report_lines.append(f"- 余额总计: {total_balance:.2f}元")
    report_lines.append(f"- 提现总计: {total_withdrawals:.2f}元")
    
    logger.info(f"报告生成耗时: {time.time() - start_time:.2f} 秒")
    return "\n".join(report_lines), total_runs, total_balance, total_withdrawals

def main():
    """主函数"""
    task_start = time.time()
    
    try:
        # 步骤1: 解析日志文件
        account_data = parse_log_files()
        
        # 步骤2: 生成报告
        report, runs, balance, withdrawals = generate_report(account_data)
        
        # 步骤3: 输出报告到日志
        logger.info("\n" + "="*50 + "\n生成报告内容:\n" + report + "\n" + "="*50)
        
        logger.info("日志分析完成，报告已生成")
    except Exception as e:
        logger.exception(f"任务执行失败: {str(e)}")
    finally:
        logger.info(f"任务总耗时: {time.time() - task_start:.2f} 秒")

if __name__ == "__main__":
    main()